<?php

/**
 * data actions.
 *
 * @package    Redsea20
 * @subpackage data
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class dataActions extends sfActions {

    public function executeIndex(sfWebRequest $request) {
        $this->researchs = Doctrine::getTable('Research')
                        ->createQuery('a')
                        ->execute();
    }

    public function executeShowResearch(sfWebRequest $request) {
        $research = Doctrine::getTable('Research')->find(array($request->getParameter('id')));
        $this->research = $research;

        $bibtex = new Structures_BibTex();
        $bibtex->content = $research->getCitation();
        $bibtex->parse();
        
        $this->genCitation = $bibtex->toCitation();
    }

    public function executeNewResearch(sfWebRequest $request) {

        $this->form = new ResearchForm();
        $this->bibentry = null;
    }

    public function executeCreateResearch(sfWebRequest $request) {
        $this->forward404Unless($request->isMethod(sfRequest::POST));

        $research = $this->processResearchForm($request, null);

        if ($research) {
            $this->success = true;
            $this->research = $research;
            $this->redirect($this->getController()->genUrl('data/showResearch?id=' . $research->id));
        }
    }

    public function processResearchForm($request, $research) {
        $paramValues = $request->getParameter('research');

        if (is_null($research))
            $paramValues['entityid'] = $this->getUser()->getAttribute("currentuser")->getId();
        else
            $paramValues['entityid'] = $research->getEntityId();

        $form = new ResearchForm($research);
        $form->bind($paramValues);

        if ($form->isValid()) {

            // get uploaded file
            $file = $request->getFiles('uploadpaper');
            
            if ($file['size'] > 0) {
                
                // open for read
                $fp = fopen($file['tmp_name'], 'r');
                $fileContent = fread($fp, filesize($file['tmp_name']));
                fclose($fp);

                // set file to paper
                $form->getObject()->researchpaper = $fileContent;
                $form->getObject()->researchpaperfilename = $file['name'];
                $form->getObject()->researchpaperfiletype = $file['type'];
                $form->getObject()->researchpaperfilesize = $file['size'];
            } else {
                
            }

            // save object
            $form->save();

            return $form->getObject();

        } else {
            $this->form = $form;
            $this->setTemplate('newResearch');

            return false;
        }
        
    }

    public function executeEditResearch(sfWebRequest $request) {
        $research = Doctrine::getTable('Research')->find(array($request->getParameter('id')));
        $this->forward404Unless($research, sprintf('Object research does not exist (%s).', $request->getParameter('id')));

        $this->form = new ResearchForm($research);
        $this->research = $research;

        $bibtex = new Structures_BibTex();
        $bibtex->content = $research->getCitation();
        $bibtex->parse();
        
        if (count($bibtex->data) > 0) {
            $this->bibentry = $bibtex->data[0];
        } else $this->bibentry = null;

        $this->setTemplate('newResearch');
    }

    public function executeUploadData(sfWebRequest $request) {

        $this->uploadedFiles = array();
        $path = sfConfig::get('sf_upload_dir').'/temp/';
        $userId = $this->getUser()->getAttribute('currentuser')->getId();
        $this->researchId = $request->getParameter('id');
        
        if($this->getRequest()->isMethod('post'))
        {
            // get uploaded file
            $files = $request->getFiles('fileUpload');

            if($files['size'] > 0)
            {
                $filename = basename($files['name']);
                $arrFilename = explode('.', $filename);
                $fileExtension = end($arrFilename);
                
                $formattedFileName = $path.reset($arrFilename).'_'.$userId.'.'.$fileExtension;

                /*
                 * Verifying whether user is trying to upload original template file or renamed file
                 *
                 * Matching the uploaded file name with Original template file names
                 */
                if( array_key_exists(strtoupper( reset($arrFilename) ), Types::$EXCEL_DATA_TEMPLATES))
                {
                    // Checking the upload limit
                    if (count(glob($path . "*")) < sfConfig::get('app_MaxExcelTemplateUpload_limit'))
                    {
                        //Moving file to server folder, i-e web->uploads->temp
                        if(!move_uploaded_file($files['tmp_name'], $formattedFileName))
                            $this->getUser()->setFlash('message', 'Unable to upload. Contact Administrator');

                        // Loads the name of newly uploaded file name along with existing uploaded files' name
                        $this->uploadedFiles = $this->getDirectoryList($path);
                    }
                    else
                    {
                        // Loads the existing files' name
                        $this->uploadedFiles = $this->getDirectoryList($path);

                        $this->getUser()->setFlash('message', 'Upload limit exceeded. You can upload four templates only');
                    }
                }
                else
                {
                    // Loads the existing files' name
                        $this->uploadedFiles = $this->getDirectoryList($path);

                        $this->getUser()->setFlash('message', 'Please upload original template file (File renaming is not allowed)');
                }
            }
            else
            {
                $this->getUser()->setFlash('message', 'Please select a valid file to upload');
            }
        }
        else
        {
            // DELETE ALL TEMPLATE FIELS UPLOADED BY USER
            foreach (Types::$EXCEL_DATA_TEMPLATES as $key => $value) {
                //echo file_exists($path.$key.'_'.$userId.'.xlsx')? 'Y<br/>':'N<br/>';
                $this->deleteFile($path.$key.'_'.$userId.'.xlsx');
            }
        }
        
        return sfView::SUCCESS;
    }

    public function deleteFile($filePath)
    {
        $_flag = FALSE;

        if(file_exists($filePath))
        {
            $_flag = unlink ($filePath);

            // Unlink doesn't delete file if it is opened and returns FALSE
            if(!$_flag)
            {
                $fileHander = fopen($filePath, 'r');
                
                if(fclose($fileHander))
                    $_flag = unlink ($filePath);

                unset ($fileHander);
            }
        }
        return $_flag;
    }

    private function getDirectoryList ($directory)
    {
        // create an array to hold directory list
        $results = array();

        // create a handler for the directory
        $handler = opendir($directory);

        // open directory and walk through the filenames
        while ($file = readdir($handler)) {

              // if file isn't this directory or its parent, add it to the results
              if ($file != "." && $file != "..")
                  $results[] = array($file, RBISUtility::byteToSize ( filesize( $directory.  $file) ));
        }

        // tidy up: close the handler
        closedir($handler);

        // done!
        return $results;
    }

    public function executeUploadResearchData(sfWebRequest $request) {
        
        /*
         * Verifying the files combination
         *
         * RULES
         * 1) User can upload Location file only, but if user uploads Depth file
         * then he/she must upload location file along with depth as Depth itself
         * is nothing.
         *
         * 2) If user wants to upload Species data then he/she must upload Location
         * file along with Species file (Note: Depth is optional in this case) but
         * if user uploads Species and Depth files then Location file would be
         * necessary as Depth itself is nothing.
         *
         * 3) 2nd point would be true in case of Attribute
         */
        
        $path = sfConfig::get('sf_upload_dir').'/temp/';
        $userId = $this->getUser()->getAttribute('currentuser')->getId();
        $fileExtension = ".xlsx";
        $filename = $path.'%1$s_'.$userId.$fileExtension;
        $_isValid = FALSE;
        $researchId = $request->getParameter('id');

        // RULE# 2
        if( file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_SPECIES)))
        {
            if( ! ($_isValid = file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_LOCATION))) )
            {
                $this->getUser()->setFlash('message', 'Please upload Location Template (Required for biological data)');
            }
        }

        // RULE# 3
        if( file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_ATTRIBUTE)))
        {
            if( ! ($_isValid = file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_LOCATION))) )
            {
                $this->getUser()->setFlash('message', $this->getUser()->getFlash('message'). '<br/>Please upload Location Template (Required for non-biological data)');
            }
        }

        // RULE# 1
        if( file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_DEPTH)))
        {
            if( ! ($_isValid = file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_LOCATION))) )
            {
                $this->getUser()->setFlash('message', $this->getUser()->getFlash('message'). '<br/>Please upload Location Template (Required for depth)');
            }
        }

        // If proper files have been uploaded then start processing the Excel Templates
        if($_isValid)
        {
            $this->processExcelTemplates($path, $fileExtension, $filename, $userId, $request->getParameter('id'));
        }

        // Loads the existing files' name
        $this->uploadedFiles = $this->getDirectoryList($path);


        $this->setTemplate('uploadData');
        //return sfView::NONE;
    }

    private function processExcelTemplates($dirPath, $fileExt, $formattedFileName, $userId, $researchId)
    {
        // Holds Error messages
        $messageCollection = array();
        
        $_isValid = FALSE;
        $objReader = PHPExcel_IOFactory::createReader('Excel2007');
        $objPHPExcel = $objReader->load( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_LOCATION) );

        $worksheet = $objPHPExcel->getActiveSheet();
        // Get column count
        $highestColCount = PHPExcel_Cell::columnIndexFromString($worksheet->getHighestColumn());
        $highestRowCount = $worksheet->getHighestRow();

        // As first row contains column headings in Excel file
        $currentRow = 2;
        //$insertBulkLocations[] = '';
        $loc = '';
        $lat = '';
        $lng = '';
        $colLocationId = '';
        $locationList = array();
        for($currentRow; $currentRow <= $highestRowCount; $currentRow++)
        {
            $colLocationId = $worksheet->getCellByColumnAndRow(0, $currentRow);

            // Reading required columns value from Location Template
            $loc = $worksheet->getCellByColumnAndRow(1, $currentRow)->getValue();
            $lat = $worksheet->getCellByColumnAndRow(2, $currentRow)->getValue();
            $lng = $worksheet->getCellByColumnAndRow(3, $currentRow)->getValue();

            // Verifying required column values in Observation/Location tabls
            if( empty ($loc) || empty ($lat) || empty ($lng))
            {
                $messageCollection[] = 'Incorrect data in Location File (Location, Lattitude and Longitude are required)';
                //$this->getUser()->setFlash('message', 'Incorrect data in Location File (Location, Lattitude and Longitude are required)');
                $_isValid = FALSE;

                break;
            }
            else
            {
                $_isValid = TRUE;

                // Need to call Jahid's function which insert locations as bulk
                // Function accept data as associative array
//                $insertBulkLocations[] = array(
//                    "location" => $loc,
//                    "lat" => $lat,
//                    "lng" => $lng,
//                    "observationdate" => $worksheet->getCellByColumnAndRow(4, $currentRow)->getValue(),
//                    "remarks" => $worksheet->getCellByColumnAndRow(5, $currentRow)->getValue(),
//                    "researchid" =>  $researchId,
//                    "dirtyid" => 0
//                );

                $newLocation = Observation::getObservationByLocation($loc);

                if($newLocation->count() > 0)
                {
                    // HALT: Notify user that Location already exists. He/She
                    // wants to use same or not. If not then rename the location
                    $messageCollection[] = $loc.' already exists. Kindly rename your location';
                    //$this->getUser()->setFlash('message', $loc.' already exists. Kindly rename your location');
                    $_isValid = FALSE;
                    
                    break;
                }

                $newLocation = new Observation ();
                $newLocation->setLocation($loc);
                $newLocation->setLat($lat);
                $newLocation->setLng($lng);
                $newLocation->setRemarks($worksheet->getCellByColumnAndRow(5, $currentRow)->getValue());
                $newLocation->setResearchid($researchId);
                $newLocation->setObservationdate($worksheet->getCellByColumnAndRow(4, $currentRow)->getValue());

                $locationList[$colLocationId->getValue()] = $newLocation;

                //echo $worksheet->getCellByColumnAndRow(0, $currentRow)->getValue().'<br />';
            }
        }
        
        // Releasing Resources
        //unset ($objReader);
        unset ($objPHPExcel);

        // Load Depth File
        $objPHPExcel = $objReader->load( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_DEPTH) );

        $worksheet = $objPHPExcel->getActiveSheet();
        // Get column count
        $highestColCount = PHPExcel_Cell::columnIndexFromString($worksheet->getHighestColumn());
        $highestRowCount = $worksheet->getHighestRow();

        // As first row contains column headings in Excel file
        $currentRow = 2;
        $colDepthId = '';
        $colDepthLocationId = '';
        $colDepth = '';
        $colDepthUnit = '';
        $depthList = array();

        // Iterating Depth Excel
        for($currentRow; $currentRow <= $highestRowCount; $currentRow++)
        {
            $colDepthId = $worksheet->getCellByColumnAndRow(0, $currentRow)->getValue();
            $colDepthLocationId = $worksheet->getCellByColumnAndRow(1, $currentRow)->getValue();
            $colDepth = $worksheet->getCellByColumnAndRow(2, $currentRow)->getValue();
            $colDepthUnit = $worksheet->getCellByColumnAndRow(3, $currentRow)->getValue();

            // Verifying required column values in Depth tables
            if( empty ($colDepthId) || empty ($colDepthLocationId) || empty ($colDepth))
            {
                $messageCollection[] = 'Incorrect data in Depth File (Depth Serial No, Location Serial No and Depth are required)';
                //$this->getUser()->setFlash('message', 'Incorrect data in Depth File (Depth Serial No, Location Serial No and Depth are required)');
                $_isValid = FALSE;

                break;
            }
            else
            {
                $_isValid = TRUE;

                if(isset ($locationList[$colDepthLocationId]))
                {
                    $newDepth = new Observationdepth();
                    $newDepth->setObservation($locationList[$colDepthLocationId]);
                    //$newDepth->setObservationid($locationList[$colDepthLocationId]->getId());
                    $newDepth->setObservationdepth($colDepth);
                    $newDepth->setUnit(Doctrine::getTable('Unit')->findOrCreate(array('unit' => $colDepthUnit)));
                    

                    $depthList[$colDepthId] = $newDepth;

                }
                else
                {
                    // HALT: Notify user that No Location exists in Location Excel against
                    // LocationId in Depth Excel (Invalid Location Reference in Depth Excel)
                    $messageCollection[] = ' Location Serial No ('. $colDepthLocationId .') doesn\'t exists in Location Template';
                    //$this->getUser()->setFlash('message', ' Location Serial No ('. $colDepthLocationId .') doesn\'t exists in Location Template');
                    $_isValid = FALSE;

                    break;
                }
            }
        }

        unset ($objPHPExcel);

        //Process SPECIES FILE
        // Load SPECIES File if uploaded by user
        if(file_exists( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_SPECIES) ))
        {
            // Load Depth File
            $objPHPExcel = $objReader->load( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_SPECIES) );
            $worksheet = $objPHPExcel->getActiveSheet();

            // Get column count
            $highestColCount = PHPExcel_Cell::columnIndexFromString($worksheet->getHighestColumn());
            $highestRowCount = $worksheet->getHighestRow();

            // As first row contains column headings in Excel file
            $currentRow = 2;
            $colSpecieId = '';
            $colSpecieName = '';
            $colSpecieQnty = '';
            $colSpecieLocId = '';
            $colSpecieDepthId = '';
            $speciesList = array();

            for($currentRow; $currentRow <= $highestRowCount; $currentRow++)
            {
                $colSpecieId = $worksheet->getCellByColumnAndRow(0, $currentRow)->getValue();
                $colSpecieName = $worksheet->getCellByColumnAndRow(1, $currentRow)->getValue();
                $colSpecieQnty = $worksheet->getCellByColumnAndRow(2, $currentRow)->getValue();
                $colSpecieLocId = $worksheet->getCellByColumnAndRow(3, $currentRow)->getValue();
                $colSpecieDepthId = $worksheet->getCellByColumnAndRow(4, $currentRow)->getValue();
                $colSpecieUnit = $worksheet->getCellByColumnAndRow(5, $currentRow)->getValue();
                
                // Verifying required column values in Species table
                if( empty ($colSpecieId) || empty ($colSpecieName) || empty ($colSpecieQnty) || empty($colSpecieUnit) || ( empty ($colSpecieLocId) && empty ($colSpecieDepthId) ))
                {
                    $messageCollection[] = 'Incorrect data in Species File (Specie Serial No, Specie Name, Quantity, Unit and Location/Depth Serial Number columns are required)';
                    //$this->getUser()->setFlash('message', 'Incorrect data in Species File (Specie Serial No, Specie Name, Quantity, Unit and Location/Depth Serial Number columns are required)');
                    $_isValid = FALSE;

                    break;
                }
                else
                {
                    $_isValid = TRUE;

                    // Create new specie in database if it doesn't exists
                    $objSepcie = Doctrine::getTable('Species')->findOrCreate(array('species' => $colSpecieName));
                    $objDepth = NULL;
                    
                    if( !empty ($colSpecieLocId))
                    {
                        if(!isset ($locationList[$colSpecieLocId]))
                        {
                            $messageCollection[] = ' Location Serial No (for Specie Serial No '.$colSpecieId.') doesn\'t match with it\'s respective ID in Location Excel File.';
                            //$this->getUser()->setFlash('message', ' Location Serial No (for Specie Serial No '.$colSpecieId.') doesn\'t match with it\'s respective ID in Location Excel File.');
                            $_isValid = FALSE;

                            break;
                        }

                        if( empty ($colSpecieDepthId))
                        {
                            //NOTE: there may be a case that user forgot to mentioned depth in species field and only
                            // mentioned location id but this location id is being reference in depth file (uploaded by user)
                            // so we can use that depth but again what if there are multiple species found on this location
                            // but with deferent depths so there is possibility that for particular specie user wants to use
                            // ZERO(0) depth, the default one, and for other he/she has mentioned depth

                            // Create ZERO(0) depth and save record because there is location but no depth
                            $objDepth = new Observationdepth();
                            $objDepth->setObservation($locationList[$colSpecieDepthId]);
                            $objDepth->setObservationdepth(0);
                            $objDepth->setUnit(Doctrine::getTable('Unit')->findOrCreate(array('unit' => 'None')));

                        }
                        else
                        {
                            //Both Location and Depth exist so verify both
                            if( isset ( $locationList[$colSpecieLocId]) && isset ( $depthList[$colSpecieDepthId]) &&
                                    ($locationList[$colSpecieLocId]->getLocation() == $depthList[$colSpecieDepthId]->getObservation()->getLocation()))
                            {
                                $objDepth = $depthList[$colSpecieDepthId];
                            }
                            else
                            {
                                $messageCollection[] = ' Location/Depth Serial No (for Specie Serial No '.$colSpecieId.') doesn\'t match with their respective IDs in Location/Depth Excel Files.';
                                //$this->getUser()->setFlash('message', ' Location/Depth Serial No (for Specie Serial No '.$colSpecieId.') doesn\'t match with their respective IDs in Location/Depth Excel Files.');
                                $_isValid = FALSE;

                                break;
                            }
                        }
                    }
                    else
                    {
                        // Location is empty so verify depth and save record if all ok
                        if(isset ($depthList[$colSpecieDepthId]))
                        {
                            $objDepth = $depthList[$colSpecieDepthId];
                        }
                        else
                        {
                            $messageCollection[] = 'Depth Serial No (for Specie Serial No '.$colSpecieId.') doesn\'t exist in Depth Excel File.';
                            //$this->getUser()->setFlash('message', 'Depth Serial No (for Specie Serial No '.$colSpecieId.') doesn\'t exist in Depth Excel File.');
                            $_isValid = FALSE;

                            break;
                        }
                    }

                    $newDepthDetail = new Observationdepthdetail();
                    $newDepthDetail->setObservationdepth($objDepth);
                    $newDepthDetail->setQuantity($colSpecieQnty);
                    $newDepthDetail->setSpecies($objSepcie);
                    $newDepthDetail->setUnit(Doctrine::getTable('Unit')->findOrCreate(array('unit' => $colSpecieUnit)));


                    $speciesList[$colSpecieId] = $newDepthDetail;
                }
            }
        }

        unset ($objPHPExcel);

        //Process ATTRIBUTE FILE
        // Load ATTRIBUTE File if uploaded by user
        if(file_exists( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_ATTRIBUTE) ))
        {
            // Load Attribute File
            $objPHPExcel = $objReader->load( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_ATTRIBUTE) );
            $worksheet = $objPHPExcel->getActiveSheet();

            // Get column count
            $highestColCount = PHPExcel_Cell::columnIndexFromString($worksheet->getHighestColumn());
            $highestRowCount = $worksheet->getHighestRow();

            // As first row contains column headings in Excel file
            $currentRow = 2;
            $colAttrId = '';
            $colAttrName = '';
            $colAttrValue = '';
            $colAttrUnit = '';
            $colAttrDepthId = '';
            $attributeList = array();

            for($currentRow; $currentRow <= $highestRowCount; $currentRow++)
            {
                $colAttrId = $worksheet->getCellByColumnAndRow(0, $currentRow)->getValue();
                $colAttrName = $worksheet->getCellByColumnAndRow(1, $currentRow)->getValue();
                $colAttrValue = $worksheet->getCellByColumnAndRow(2, $currentRow)->getValue();
                $colAttrUnit = $worksheet->getCellByColumnAndRow(3, $currentRow)->getValue();
                $colAttrDepthId = $worksheet->getCellByColumnAndRow(4, $currentRow)->getValue();

                // Verifying required column values in Depth tables
                if( empty ($colAttrId) || empty ($colAttrName) || empty ($colAttrValue) || empty($colAttrUnit) || empty($colAttrDepthId))
                {
                    $messageCollection[] = 'Incorrect data in Attribute File (Attribute Serial No, Attribute Name, Attribute Value, Unit and Depth Serial Number columns are required)';
                    //$this->getUser()->setFlash('message', 'Incorrect data in Attribute File (Attribute Serial No, Attribute Name, Attribute Value, Unit and Depth Serial Number columns are required)');
                    $_isValid = FALSE;

                    break;
                }
                else
                {
                    $_isValid = TRUE;

                    // Create new attribute in database if it doesn't exists
                    $objAttribute = Doctrine::getTable('Attribute')->findOrCreate(array('attributename' => $colAttrName));
                    $objDepth = NULL;

                    if(!isset ($depthList[$colAttrDepthId]))
                    {
                        $messageCollection[] = ' Depth Serial No (for Attribute Serial No '.$colAttrId.') doesn\'t match with it\'s respective ID in Depth Excel File.';
                        //$this->getUser()->setFlash('message', ' Depth Serial No (for Attribute Serial No '.$colAttrId.') doesn\'t match with it\'s respective ID in Depth Excel File.');
                        $_isValid = FALSE;

                        break;
                    }

                    $newDepthAttribute = new Observationdepthattribute();
                    //$newDepthAttribute->setAttribute($objAttribute);
                    $newDepthAttribute->setAttributeid($objAttribute->getId());
                    $newDepthAttribute->setAttributevalue($colAttrValue);
                    $newDepthAttribute->setObservationdepth($depthList[$colAttrDepthId]);
                    $newDepthAttribute->setUnit(Doctrine::getTable('Unit')->findOrCreate(array('unit' => $colAttrUnit)));
                    
                    $attributeList[$colAttrId] = $newDepthAttribute;
                }
            }
        }

        //echo $depthList[1]->save();
        unset ($objReader);
        unset ($objPHPExcel);

        try{
            if($_isValid)
            {
                //echo $speciesList[1]->getUnit ()->getUnit (); //'SAVING LOCATIONS';
                foreach ($speciesList as $value) {
                    $value->save();
                }
                
                foreach ($depthList as $oDepth) {
                    $oDepth->save();
                }
                
                foreach ($locationList as $observation) {
                    $observation->save();
                }
                
                foreach ($attributeList as $attr) {
                    $attr->save();
                }
            }
                //ObservationTable::getInstance()->insertCollection($insertBulkLocations);
        }
        catch (Exception $e) {
            $messageCollection[] = $e->getTraceAsString();
            $this->error_msg = $e->getTraceAsString();
        }

        $this->getUser()->setFlash('message', $messageCollection);
    }

    /*
     * Verfies the depth against location in Depth Template (EXCEL) and
     * if exists then create depth entries in database
     */
    private function hasDepth($locationId, $formattedFileName) {

        // Check if Depth Template Exists
        if(file_exists(sprintf($filename, Types::$EXCEL_DATA_TEMPLATES_LOCATION)))
        {
            $objReaderDepth = PHPExcel_IOFactory::createReader('Excel2007');
            $objPHPExcelDepth = $objReader->load( sprintf($formattedFileName, Types::$EXCEL_DATA_TEMPLATES_DEPTH) );

            // As first row contains column headings in Excel file
            $currentRow_Depth = 2;
            $worksheet_Depth = $objPHPExcelDepth->getActiveSheet();

            $highestRowCount = $worksheet_Depth->getHighestRow();

            // Iterate Depth Template
            for($currentRow_Depth; $currentRow_Depth <= $highestRowCount; $currentRow_Depth)
            {

            }

            // Releasing Resources
            unset ($objReaderDepth);
            unset ($objPHPExcelDepth);
        }
    }

    public function executeDownloadTemplate(sfWebRequest $request) {
        $templateId = $request->getParameter('templateId');

        $templateFile = '';
        

        if(isset ($templateId))
        {
            switch ($templateId) {
                case Types::$EXCEL_DATA_TEMPLATES[Types::$EXCEL_DATA_TEMPLATES_LOCATION]:
                    $templateFile = sfConfig::get('sf_upload_dir').'/Excel Templates/Location.xlsx';
                    break;
                case Types::$EXCEL_DATA_TEMPLATES[Types::$EXCEL_DATA_TEMPLATES_DEPTH]:
                    $templateFile = sfConfig::get('sf_upload_dir').'/Excel Templates/Depth.xlsx';
                    break;
                case Types::$EXCEL_DATA_TEMPLATES[Types::$EXCEL_DATA_TEMPLATES_SPECIES]:
                    $templateFile = sfConfig::get('sf_upload_dir').'/Excel Templates/Species.xlsx';
                    break;
                case Types::$EXCEL_DATA_TEMPLATES[Types::$EXCEL_DATA_TEMPLATES_ATTRIBUTE]:
                    $templateFile = sfConfig::get('sf_upload_dir').'/Excel Templates/Attribute.xlsx';
                    break;

                default:
                    break;
            }

            $objReader = PHPExcel_IOFactory::createReader('Excel2007');
            $objPHPExcel = $objReader->load($templateFile);

            // basename returns the base name of the given path.
            // Redirect output to a client’s web browser (Excel2007)
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="'. basename( $templateFile ) .'"');
            header('Cache-Control: max-age=0');

            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
            $objWriter->save('php://output');

            //echo $templateFile;
        }

        //echo isset ($templateId)? $templateId: '1';

        return sfView::NONE;
    }

    public function executeUpdateResearch(sfWebRequest $request) {
        $this->forward404Unless($request->isMethod(sfRequest::POST) || $request->isMethod(sfRequest::PUT));

        $paramValues = $request->getParameter('research');
        $id = $paramValues['id'];
        $this->forward404Unless($research = Doctrine::getTable('Research')->find(array($id)), sprintf('Object research does not exist (%s).', $id));

        $object = $this->processResearchForm($request, $research);
        
        if ($object) {
            $this->setTemplate('showResearch');
            $this->success = true;
            $this->research = $object;

            $bibtex = new Structures_BibTex();
            $bibtex->content = $object->getCitation();
            $bibtex->parse();
            
            $this->genCitation = $bibtex->toCitation();
        } else {
            $bibtex = new Structures_BibTex();
            $bibtex->content = $research->getCitation();
            $bibtex->parse();

            if (count($bibtex->data) > 0) {
                $this->bibentry = $bibtex->data[0];
            } else $this->bibentry = null;
        }

    }

    public function executeDownloadResearchPaper(sfWebRequest $request) {
        $research = Doctrine::getTable('Research')->find($request->getParameter('id'));

        $this->getResponse()->setContentType($research->researchpaperfiletype);
        $this->getResponse()->setHttpHeader('Content-length', $research->researchpaperfilesize);
        $this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename="'.$research->researchpaperfilename.'"');

        echo $research->researchpaper;

        return sfView::NONE;
    }

    public function executeNewObservation(sfWebRequest $request) {
        $research_id = $request->getParameter('id');
        $this->research = Doctrine::getTable('Research')->find(array($research_id));

        $this->form = new ObservationForm();
    }

    public function executeShowObservation(sfWebRequest $request) {
        $id = $request->getParameter('id');

        $this->research = Doctrine::getTable('Research')->find(array($id));
        $this->forward404Unless($this->research, sprintf("Research %s not found", $id));

        $this->observations = $this->research->getObservation();
        $this->forward404Unless($this->observations);

        // this form used for pop up dialog 
        $this->form = new ObservationForm();
    }

    public function executeUpdateObservation(sfWebRequest $request) {

        $researchId = $request->getParameter('id');

        // decode json-formatted parameters
        $inserts = json_decode($request->getParameter('inserts'), true);
        $removes = json_decode($request->getParameter('removes'), true);
        $updates = json_decode($request->getParameter('updates'), true);

        try {
            // proses bulk insert
            if ($inserts) {
                for($i = 0; $i < count($inserts); $i++) {
                    $inserts[$i]['researchid'] = $researchId;
                }
                ObservationTable::getInstance()->insertCollection($inserts);
            }

            // process bulk update
            if ($updates) {                
                ObservationTable::getInstance()->updateCollection($updates);
            }

            //process bulk delete
            if ($removes)
                ObservationTable::getInstance()->delete($removes);

        } catch (Exception $e) {
            $this->error_msg = $e->getTraceAsString();
        }

        // prepare for view
        $this->research = Doctrine::getTable('Research')->find(array($request->getParameter('id')));
        $this->forward404Unless($this->research);
        $this->observations = $this->research->getObservation();
        $this->forward404Unless($this->observations);
    }

    public function executeShowSpecies(sfWebRequest $request) {

        $this->observation = Doctrine::getTable('observation')->find(array($request->getParameter('obs')));

        if ($request->hasParameter('depth')) {
            if ($this->getRequestParameter('depth') == 'new') {
                $this->currentDepth = "";
            } else {
                $this->currentDepth = Doctrine::getTable('Observationdepth')->findOneBy('id', $this->getRequestParameter('depth'));
//                echo 'depthid:' . $this->getRequestParameter ('depth');
            }
        } else {
            // if depth is not defined then redirect to the first depth
            $firstDepth = Doctrine::getTable('Observationdepth')->findFirstDepth('observationid = ?', array($request->getParameter('obs')));
            if ($firstDepth)
                $this->redirect($this->getController()->genUrl('data/showSpecies?obs=' . $request->getParameter('obs') . '&depth=' . $firstDepth->getId()));
            else
                $this->redirect($this->getController()->genUrl('data/showSpecies?obs=' . $request->getParameter('obs') . '&depth=new'));
        }

        $this->page = $request->getParameter('page', 1);

        $this->researchid = $this->observation->getResearch()->getId();
    }

    public function executeSpecies(sfWebRequest $request) {
        $this->page = $request->getParameter('page', 1);
        $this->currentDepth = Doctrine::getTable('Observationdepth')->findOneBy('id', $this->getRequestParameter('depth'));
    }

    public function executeUpdateSpecies(sfWebRequest $request) {
        $inserts = json_decode($request->getParameter('inserts'), true);
        $updates = json_decode($request->getParameter('updates'), true);
        $removes = json_decode($request->getParameter('removes'), true);

        if ($inserts) {
            ObservationdepthdetailTable::getInstance()->bulkInsertUpdate($inserts);
        }

        if ($updates) {
            ObservationdepthdetailTable::getInstance()->bulkInsertUpdate($updates);
        }

        if ($removes)
            ObservationdepthdetailTable::getInstance()->delete($removes);

        if ($request->hasParameter('obs')) {
            // if request has parameters obs (observation id),
            // this indicates new depth. then redirect to show the latest depth
            $latestDepth = Doctrine::getTable('Observationdepth')->findLatestDepth('observationid = ?', $request->getParameter('obs'));
            $this->redirect($this->getController()->genUrl('data/showSpecies?obs=' . $request->getParameter('obs') . '&depth=' . $latestDepth->getId()));
        } else {
            $this->currentDepth = Doctrine::getTable('Observationdepth')->findOneBy('id', $this->getRequestParameter('depth'));
            $this->page = $request->getParameter('page');
            $this->setTemplate('species');
        }
    }

    public function executeCreateSpecies(sfWebRequest $request) {

        $this->getLogger()->debug('newSpecies');

        $species = $request->getParameter('data');

        if (empty($species))
            return $this->renderText('false');
        else {
            $newSp = SpeciesTable::getInstance()->insertIfNotExist(array('species' => $species));

            $this->getLogger()->debug($newSp);

            return ($newSp) ? $this->renderText($newSp->getId()) : $this->renderText($newSp);
        }
    }

    public function executeUpdateDepth(sfWebRequest $request) {
        $formParam = $request->getParameter('depthForm');

        foreach($formParam as $key => $value) {
            $this->getLogger()->debug('updateDepth: ' . $key .' => ' . $value);

            foreach($value as $r => $m) {
                $this->getLogger()->debug('update: ' . $r .' => ' . $m);
            }

        }

        $depthid = $formParam[0]['value'];
        $depth = $formParam[2]['value'];

        if (empty($depthid)) {
            // if id is empty then it is new depth. depth value must not empty
            if (empty($depth)) throw new Exception('empty depth value');

//            $obsDepth = new Observationdepth();

        } else {
            $obsDepth = ObservationdepthTable::getInstance()->find($depthid);
            $obsDepth->observationdepth = $depth;
        }

        $obsDepth->save();

        return sfView::NONE;
    }

    public function executeDeleteDepth(sfWebRequest $request) {

//        $this->getLogger()->debug('referer: ' . $request->getReferer());

        $depth = $this->getRequestParameter('depth');
        $obs = $this->getRequestParameter('obs');

        $successDelete = Doctrine::getTable('Observationdepth')->deleteById($depth);

        // after deleting a depth, show depth before or after the deleted depth.
        // if there's no remaining depth, then create new depth
        $depthView;
        if (!$successDelete) {
            $this->getUser()->setFlash('deleteMsg', 'Unable to delete this depth, remove all its details and attributes before delete a depth.');
            $depthView = $depth;
        } else {
            $nextDepth = Doctrine::getTable('Observationdepth')->findOneBeforeOrAfter($depth, $obs);
            if ($nextDepth)
                $depthView = $nextDepth->id;
            else
                $depthView = 'new';
        }

        if (strpos($request->getReferer(), 'Species')) {
            $this->redirect($this->getController()->genUrl('data/showSpecies?obs=' . $request->getParameter('obs') . '&depth=' . $depthView));
        } else {
            $this->redirect($this->getController()->genUrl('data/showAttribute?obs=' . $request->getParameter('obs') . '&depth=' . $depthView));
        }
    }

    public function executeSearchSpecies(sfWebRequest $request) {
        $term = $request->getParameter('term');
        $maxRows = $request->getParameter('maxRows');
        $similars = Doctrine::getTable('species')
                        ->findWithLimit('species LIKE ?', '%' . $term . '%', $maxRows);

        $items = array();
        foreach ($similars as $sp) {
            $item['id'] = $sp->getId();
            $item['label'] = $sp->getSpecies();
            $item['value'] = strip_tags($sp->getSpecies());
            array_push($items, $item);
        }

        return $this->renderText(json_encode($items));
    }

    public function executeSearchTag(sfWebRequest $request) {
        $term = $request->getParameter('term');
        $maxRows = $request->getParameter('maxRows');

        $similars = Doctrine::getTable('Observationdepthdetail')
                        ->getSimilarTags($term);

        $items = array();
        foreach ($similars as $tag) {
            $item['label'] = $tag;
            $item['value'] = $tag;
            $items[] = $item;
        }
        $data = json_encode($items);
//        $this->logMessage('similars: '.$data, 'debug');

        return $this->renderText($data);
    }

    public function executeSearchUnit(sfWebRequest $request) {
        $term = $request->getParameter('term', "");
        $maxRows = $request->getParameter('maxRows', 1000);

        $similars = Doctrine::getTable('Unit')
                        ->findWithLimit('unit LIKE ?', '%' . $term . '%', $maxRows);

        $items = Array();
        foreach ($similars as $sp) {
            $item['id'] = $sp->getId();
            $item['label'] = $sp->getUnit();
            $item['value'] = $sp->getId();
//            $item['unitid'] = $sp->getId();
//            $item['unit'] = $sp->getUnit();
            array_push($items, $item);
        }

        return $this->renderText(json_encode($items));
    }

    public function executeShowAttribute(sfWebRequest $request) {
        $this->observation = Doctrine::getTable('observation')->find(array($request->getParameter('obs')));

        if ($request->hasParameter('depth')) {
            if ($this->getRequestParameter('depth') == 'new') {
                $this->currentDepth = "";
            } else {
                $this->currentDepth = Doctrine::getTable('Observationdepth')->findOneBy('id', $this->getRequestParameter('depth'));
            }
        } else {
            // if depth is not defined then redirect to the first depth
            $firstDepth = Doctrine::getTable('Observationdepth')->findFirstDepth('observationid = ?', array($request->getParameter('obs')));
            if ($firstDepth)
                $this->redirect($this->getController()->genUrl('data/showAttribute?obs=' . $request->getParameter('obs') . '&depth=' . $firstDepth->getId()));
            else
                $this->redirect($this->getController()->genUrl('data/showAttribute?obs=' . $request->getParameter('obs') . '&depth=new'));
        }

//        echo 'current depth id: ' . $this->currentDepth->id;

        $this->page = $request->getParameter('page', 1);

        $this->researchid = $this->observation->getResearch()->getId();
    }

    public function executeSearchAttribute(sfWebRequest $request) {
        $term = $request->getParameter('term');
        $maxRows = $request->getParameter('maxRows');
        $similars = Doctrine::getTable('Attribute')
                        ->findWithLimit('attributename LIKE ?', '%' . $term . '%', 10);

        $items = Array();
        foreach ($similars as $attr) {
            $item['id'] = $attr->id;
            $item['label'] = $attr->attributename;
            $item['value'] = strip_tags($attr->attributename);
            $item['unitid'] = $attr->Unit->unit;
            array_push($items, $item);
        }

        return $this->renderText(json_encode($items));
    }

    public function executeUpdateAttribute(sfWebRequest $request) {
        $inserts = json_decode($request->getParameter('inserts'), true);
        $updates = json_decode($request->getParameter('updates'), true);
        $removes = json_decode($request->getParameter('removes'), true);

        if ($inserts) {
            $inserts = ObservationdepthattributeTable::getInstance()->bulkInsertUpdate($inserts);
        }

        if ($updates)
            ObservationdepthattributeTable::getInstance()->bulkInsertUpdate($updates);

        if ($removes)
            ObservationdepthattributeTable::getInstance()->delete($removes);

        if ($request->hasParameter('obs')) {
            // if request has parameters obs (observation id),
            // this indicates new depth. then redirect to show the latest depth
            $latestDepth = Doctrine::getTable('Observationdepth')->findLatestDepth('observationid = ?', $request->getParameter('obs'));
            $this->redirect($this->getController()->genUrl('data/showAttribute?obs=' . $request->getParameter('obs') . '&depth=' . $latestDepth->getId()));
        } else {
            $this->currentDepth = Doctrine::getTable('Observationdepth')->findOneBy('id', $this->getRequestParameter('depth'));
            $this->page = $request->getParameter('page');
            $this->setTemplate('attribute');
        }
    }

    public function executeAttribute(sfWebRequest $request) {
        $this->page = $request->getParameter('page', 1);
        $this->currentDepth = Doctrine::getTable('Observationdepth')->findOneBy('id', $this->getRequestParameter('depth'));
    }

    public function executeCreateAttribute(sfWebRequest $request) {

//        return $this->renderText(66);

        $this->getLogger()->debug('newAttribute');

        $attribute = trim($request->getParameter('attribute'));
        $unit = trim($request->getParameter('unit'));

        if (empty($attribute) || empty($unit))
            return $this->renderText('false');
        else {
            $newAttr = AttributeTable::getInstance()->insertIfNotExist(
                    array('attributename' => $attribute, 'unit' => $unit));

            $this->getLogger()->debug($newAttr);

            return ($newAttr) ? $this->renderText($newAttr->getId()) : $this->renderText($newAttr);
        }
    }

    /**
     * Given a research id, then show its overlays
     * @param sfWebRequest $request
     */
    public function executeShowOverlay(sfWebRequest $request) {
        $this->form = new OverlayUploadForm();
        $this->overlayform = new ResearchoverlayForm();

        $this->overlays = Doctrine_Core::getTable('researchoverlay')->findByDql("researchid = ?", $request->getParameter('id'));

        $this->id = $request->getParameter('id');

        if ($this->getUser()->hasAttribute('overlayid')) {
            $this->overlayid = $this->getUser()->getAttribute('overlayid');
            $this->getUser()->getAttributeHolder()->remove('overlayid');
        } elseif ($this->overlays->count() > 0) {
            $this->overlayid = $this->overlays->getFirst()->id;
//            $this->overlayform = new ResearchoverlayForm($this->overlays->getFirst());
        }
        $this->setLayout('visualization');
    }

    /**
     * Upload a file to overlay
     * @param sfWebRequest $request
     */
    public function executeUploadOverlay(sfWebRequest $request) {

        $form = new OverlayUploadForm();

        // upload new overlay image
        if ($request->isMethod(sfWebRequest::POST)) {

            $form->bind($request->getParameter('uploadoverlay'), $request->getFiles('uploadoverlay'));
            if ($form->isValid()) {
                $file = $form->getValue('upload');
//                $filename = basename($file->getOriginalName(), $file->getOriginalExtension()); //or whatever name
//                $extension = $file->getExtension($file->getOriginalExtension());
//                $filepath = sfConfig::get('sf_upload_dir') . '\\' . $filename . $extension;
//                $file->save($filepath);

                // save image to database
                $newOverlay = new Researchoverlay('researchoverlay', true);
                $newOverlay->setResearchid($request->getParameter('id'))
                        ->setOverlaytitle($filename)
                        ->setOverlaytype($extension)
                        ->setSlat(9)
                        ->setWlng(31)
                        ->setNlat(28)
                        ->setElng(46);

                try {
                    $fp = fopen($file->getTempName(), 'r');
                    $fileContent = fread($fp, filesize($file->getTempName()));
                    $this->getLogger()->debug('size of ' . $file->getTempName() . ': ' . filesize($file->getTempName()));
//                    $fileContent = addslashes($fileContent);
                    fclose($fp);

                    $newOverlay->overlayimage = $fileContent;
                    $newOverlay->save();
                } catch (Exception $e) {
                    die($e->getMessage());
                }
            }
        }

        $this->getUser()->setAttribute('overlayid', $newOverlay->id);

        $this->redirect($this->getController()->genUrl('data/showOverlay?id=' . $request->getParameter('id')));
    }

    /**
     * Update overlay value
     * @param sfWebRequest $request
     */
    public function executeUpdateOverlay(sfWebRequest $request) {

        $slat = $request->getParameter('slat');
        $nlat = $request->getParameter('nlat');
        $wlng = $request->getParameter('wlng');
        $elng = $request->getParameter('elng');

        $overlay = Doctrine::getTable('Researchoverlay')->findOneBy('id', $request->getParameter('overlayid'));
        $overlay->slat = $slat;
        $overlay->nlat = $nlat;
        $overlay->wlng = $wlng;
        $overlay->elng = $elng;
//        $overlay->modifiedbyuserid = $this->getUser()->getAttribute('currentuser')->id;

        $overlay->save();

        sfView::NONE;
    }

    public function executeSaveOverlay(sfWebRequest $request) {
        
        // upload new overlay image
        if ($request->isMethod(sfWebRequest::POST)) {

            // new overlay image, set initial location
            $formParams = $request->getParameter('researchoverlay');

            if (!empty($formParams['id'])) {
                $researchOverlay = ResearchoverlayTable::getInstance()->find($formParams['id']);
                $overlayForm = new ResearchoverlayForm($researchOverlay);
            }
            else {
                $overlayForm = new ResearchoverlayForm();
                $formParams['researchid'] = $request->getParameter('id');
                $formParams['slat'] = 9;
                $formParams['wlng'] = 31;
                $formParams['nlat'] = 28;
                $formParams['elng'] = 46;
            }

            $uploadForm = new OverlayUploadForm();
            $uploadForm->bind($request->getParameter('uploadoverlay'), $request->getFiles('uploadoverlay'));

            // process uploded file
            if ($uploadForm->isValid()) {
                $file = $uploadForm->getValue('upload');

//                foreach($file as $key => $value) {
//                    $this->getLogger()->debug('upload: ' . $file);
//                }

                if (!empty($file)) {

                    try {
                        // resize image, since the database doesnt allow large data
                        $image = new CustomImage($file->getTempName());
                        $image->resizeToWidth('768');
                        $image->save($file->getTempName());
                        
                        $fp = fopen($file->getTempName(), 'r');
                        $fileContent = fread($fp, filesize($file->getTempName()));
                        $this->getLogger()->debug('size of ' . $file->getTempName() . ': ' . filesize($file->getTempName()));
    //                    $fileContent = addslashes($fileContent);
                        fclose($fp);

                        
                        $formParams['overlayimage'] = $fileContent;

                    } catch (Exception $e) {
                        $this->getLogger($e->getTraceAsString());
                        throw $e;
//                        die($e->getMessage());
                    }

                } else {
                    // keep existing file
                    $formParams['overlayimage'] = $researchOverlay->overlayimage;
                }

            } else {
                $this->getLogger()->debug('upload: ' . $uploadForm->isValid());
            }

            // now process the form
            $overlayForm->bind($formParams);

            if ($overlayForm->isValid()) {
                $overlayObject = $overlayForm->save();
                
            } else {
//                $overlayForm->getGlobalErrors();
                $this->getLogger()->debug('form: ' . $overlayForm->getGlobalErrors());
                $this->getLogger()->debug('form: ' . $overlayForm->getErrorSchema());
            }
        }

        $this->getUser()->setAttribute('overlayid', $overlayObject->id);

        $this->redirect($this->getController()->genUrl('data/showOverlay?id=' . $request->getParameter('id')));
    }

    public function executeGetOverlayData(sfWebRequest $request) {
        $overlay = Doctrine::getTable('Researchoverlay')->findOneBy('id', $request->getParameter('overlayid'));

        $params = array();

        $params['id'] = $overlay->id;
        $params['researchid'] = $overlay->researchid;
        $params['overlaytitle'] = $overlay->overlaytitle;
        $params['overlaydescription'] = $overlay->overlaydescription;
        $params['slat'] = $overlay->slat;
        $params['nlat'] = $overlay->nlat;
        $params['wlng'] = $overlay->wlng;
        $params['elng'] = $overlay->elng;

        return $this->renderText(json_encode($params));
    }

    public function executeDeleteOverlay(sfWebRequest $request) {
        $overlay = Doctrine::getTable('Researchoverlay')->findOneBy('id', $request->getParameter('overlayid'));
        $overlay->delete();

//        $this->redirect($this->getController()->genUrl('map/showOverlay?id='.$request->getParameter('id')));
        $this->redirect($request->getReferer());
    }

    public function executeResearchCollaboration(sfWebRequest $request) {
        $this->researchList = Research::getResearchListByStatus(null, $this->getUser()->getAttribute("currentuser")->getId(), 1);

        return sfView::SUCCESS;
    }

    public function executeGetObjectUnit(sfWebRequest $request) {

        if ($request->getParameter('type') == 'attribute') {
            $attr_units = ObjectunitTable::getInstance()->findAttributes($request->getParameter('id'));
        } else if($request->getParameter('type') == 'species') {
            $attr_units = ObjectunitTable::getInstance()->findBySpeciesName($request->getParameter('name'));
        }

        $units = array();

        foreach ($attr_units as $unit) {
            $units[] = array('label' => $unit['unit'], 'value' => $unit['unitid']);
        }

        return $this->renderText(json_encode($units));
    }

    public function executeGetBibtex(sfWebRequest $request) {
        $research = Doctrine::getTable('Research')->find($request->getParameter('id'));

        $this->getResponse()->setContentType("text/plain");
        $this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename="citation.bib"');

        echo $research->citation;

        return sfView::NONE;
    }

    public function executeNewUnitForm($request) {
        
        return sfView::SUCCESS;
    }

    public function executeNewAttributeForm($request) {
        return sfView::SUCCESS;
    }

    public function executeCreateUnit($request) {
        if ($request->getParameter('unit') == "")
            return $this->renderText('false');
        $isExist = UnitTable::getInstance()->exists(array('unit' => $request->getParameter('unit')));
        if ($isExist) {
            return $this->renderText('false');
        } else {
            $unit = new Unit();
            $unit->setUnit($request->getParameter('unit'))->save();
            return $this->renderText('true');
        }
    }

    public function executeGetAttribute($request) {
        $result = AttributeTable::getInstance()->selectBy(
                array("id", "attributename"));
        $attributes = array();
        foreach($result as $row) {
            $attributes[] = array('label' => $row['attributename'], 'value' => $row['id']);
        }
        return $this->renderText(json_encode($attributes));
    }

    public function executeGetLocation($request) {
        $researchid = $request->getParameter('id');
        $observations = ObservationTable::getInstance()->findByDql("researchid = ?", $researchid);

        $markers = array();
        foreach($observations as $obs) {
            $marker = array(
                'id' => $obs->getId(),
                'lat' => $obs->getLat(),
                'lng' => $obs->getLng(),
                'location' => $obs->getLocation()
            );
            $markers[] = $marker;
        }

        $data = json_encode($markers);

        $this->getLogger()->debug($data);

        return $this->renderText($data);
    }

}
